
#ifndef __SYSLOG_UTIL_H__
#define __SYSLOG_UTIL_H__


typedef unsigned char  byte;
typedef unsigned short word;

const size_t SYSLOG_MAX_PATH = MAX_PATH;


struct file_handle_t
{
	file_handle_t( ) : file( nullptr ) { }

#if defined WINDOWSSYSLOG_USE_CSTDLIB_FILE
	file_handle_t( FILE* f ) : file( f ) { }
	operator bool( ) const { return file != nullptr; }

	FILE* file;
#else
	file_handle_t( HANDLE f ) : file( f ) { }
	operator bool( ) const { return file != nullptr && file != INVALID_HANDLE_VALUE; }

	HANDLE file;
#endif
};

const file_handle_t null_file_handle( nullptr );

file_handle_t open_logfile( LPCTSTR filename );
file_handle_t open_stdout( );
void close( file_handle_t file );
size_t write( file_handle_t file, const byte* buffer, size_t buf_size );
void flush( file_handle_t file );


void unset_read_only_attrib( LPCTSTR file_name );
void set_read_only_attrib( LPCTSTR file_name );


bool get_reg_value( HKEY from, LPCTSTR name, DWORD* val );
bool get_reg_value( HKEY from, LPCTSTR name, TCHAR buffer[ ], DWORD buf_size );


inline SOCKET tcp_socket( ) { return socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); }
inline SOCKET udp_socket( ) { return socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); }


#pragma pack( push, 2 )
struct date_time // occupies 10 bytes
{
	word year;
	byte month;
	byte day;

	byte day_of_week;

	byte hours;
	byte minutes;
	byte seconds;

	word msecs;
};
#pragma pack( pop )

date_time get_system_time( );
date_time get_local_time( );

enum date_time_compare
{
	to_year,
	to_month,
	to_day,
	to_hour,
	to_minute
};

const TCHAR* dt_compare_string[ ];

bool are_dates_the_same( date_time dt1, date_time dt2, date_time_compare compare = to_day );


int print_timestamp( char* buffer, size_t buf_size, date_time timestamp, bool date = true, bool time = true, bool msec = true );
int print_ip( char* buffer, size_t buf_size, IN_ADDR addr );
int print_facility_severity( char* buffer, size_t buf_size, int PRI );

template <size_t Size>
inline int print_timestamp( char ( &buffer )[ Size ], date_time timestamp, bool date = true, bool time = true, bool msec = true )
{
	return print_timestamp( buffer, Size, timestamp, date , time , msec );
}

template <size_t Size>
inline int print_ip( char( &buffer )[ Size ], IN_ADDR addr )
{
	return print_ip( buffer, Size, addr );
}

template <size_t Size>
inline int print_facility_severity( char( &buffer )[ Size ], int PRI )
{
	return print_facility_severity( buffer, Size, PRI );
}


bool regex_check( const char* regex, const char* checked_string );

struct syslog_regex_t
{
	bool check( const char* checked_string ) const { return regex_check( expression, checked_string ); }
	bool check( const byte* checked_string ) const { return regex_check( expression, ( const char* ) checked_string ); }

	static const size_t max_len = WINDOWSSYSLOG_REGEX_SIZE;
	char expression[ max_len ];
};


#endif // __SYSLOG_UTIL_H__
